package com.sharelords.icp.web.aop;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;

/**
 * 日志输出JDK动态代理
 *
 * @author 夜舞旋
 */
public class LogExportProxy<T> implements MethodInterceptor {

    private T t;

    /**
     * 日志信息
     **/
    private String systemOutPrintStr;

    public String getSystemOutPrintStr() {
        return systemOutPrintStr;
    }

    /**
     * 获取被代理实例
     */
    public T getInstance(T target) {
        this.t = target;
        // 创建加强器，用来创建动态代理类
        Enhancer enhancer = new Enhancer();
        // 为加强器指定要代理的业务类（即：为下面生成的代理类指定父类）
        enhancer.setSuperclass(this.t.getClass());
        // 设置回调：对于代理类上所有方法的调用，都会调用CallBack，而Callback则需要实现intercept()方法进行拦
        enhancer.setCallback(this);
        // 创建动态代理类对象并返回
        return (T) enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        try (ByteArrayOutputStream baoStream = new ByteArrayOutputStream(1024)) {
            try (PrintStream cacheStream = new PrintStream(baoStream)) {
                try (PrintStream oldStream = System.out) {
                    // 不打印到控制台
                    System.setOut(cacheStream);
                    // 执行被代理者的方法
                    Object result = proxy.invokeSuper(obj, args);

                    String strMsg = baoStream.toString();
                    // 还原到控制台输出
                    System.setOut(oldStream);
                    System.out.println(strMsg);
                    this.systemOutPrintStr = strMsg;
                    return result;
                }
            }
        }
    }
}
